package com.umeox.ota.service;

import static com.umeox.ota.mvvm.viewModel.MainViewModel.SP_IS_LOCAL_UPDATE;

import android.app.IntentService;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.Log;

import androidx.annotation.Nullable;

import com.umeox.ota.interact.callback.IDownloadInter;
import com.umeox.ota.data.constant.Constant;
import com.umeox.ota.data.constant.TRIGGER;
import com.umeox.ota.data.local.RecordData;
import com.umeox.ota.gloable.App;
import com.umeox.ota.utils.ActivityCollector;
import com.umeox.ota.utils.NotifyUtils;
import com.umeox.ota.utils.Utils;
import com.abupdate.fotainject.FotaInject;
import com.abupdate.fotainject.FotaInjector;
import com.abupdate.iot_libs.OtaAgentPolicy;
import com.abupdate.iot_libs.data.local.OtaEntity;
import com.abupdate.iot_libs.data.remote.VersionInfo;
import com.abupdate.iot_libs.engine.otaStatus.OtaStatus;
import com.abupdate.iot_libs.engine.otaStatus.OtaStatusMgr;
import com.abupdate.iot_libs.engine.policy.PolicyManager;
import com.abupdate.iot_libs.engine.security.FotaException;
import com.abupdate.iot_libs.engine.thread.Dispatcher;
import com.abupdate.iot_libs.engine.thread.NamedRunnable;
import com.abupdate.iot_libs.interact.callback.ICheckVersionCallback;
import com.abupdate.iot_libs.interact.callback.IDownSimpleListener;
import com.abupdate.iot_libs.interact.callback.IRebootUpgradeCallBack;
import com.abupdate.iot_libs.interact.callback.InstallListener;
import com.abupdate.iot_libs.utils.NetUtils;
import com.abupdate.iot_libs.utils.SPFTool;
import com.abupdate.sdk_annotation.Inject;
import com.abupdate.trace.Trace;

import java.util.List;
import java.util.Map;

/**
 * @author fighter_lee
 * @date 2018/7/10
 */
public class OtaService extends IntentService {

    private static final String TAG = "OtaService";
    public static final String ACTION_CHECK_VERSION_TASK = "action_com_abupdate_check_version_task";
    public static final String ACTION_DOWNLOAD_TASK = "action_com_abupdate_download_task";
    public static final String ACTION_INSTALL_TASK = "action_com_abupdate_install_task";
    public static final String ACTION_LOCAL_INSTALL_TASK = "action_com_abupdate_local_install_task";
    public static final String ACTION_SHOW_NOTIFICATION = "action_com_abupdate_show_notification";
    public static final String EXTRA_PARAM1 = "extra_com_abupdate_param";
    public static final String EXTRA_PARAM2 = "extra_com_abupdate_param_local_file_path";
    OtaBinder otaBinder = new OtaBinder();

    private FotaInject fotaInject;

    @Inject
    OtaEntity otaEntity;

    @Inject
    PolicyManager policyManager;

    static ICheckVersionCallback iCheckVersionCallback;

    static IDownloadInter iDownListener;

    static IRebootUpgradeCallBack iRebootUpgradeCallBack;

    /**
     * 通过界面触发
     */
    private boolean uiTrigger;

    /**
     * 后台强制触发
     */
    private boolean autoTrigger;

    public OtaService() {
        super("OtaService");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Trace.d(TAG, "onStartCommand() ");
        return super.onStartCommand(intent, flags, startId);
    }

    private void checkVersionTask(Intent intent) {
        Trace.d(TAG, "checkVersionTask start");
        final String trigger = intent.getStringExtra(EXTRA_PARAM1);
        //判定是否自动检测
        boolean isAutoCheck = TRIGGER.CHECK.CHECK_CLIENT.name().equals(trigger);
        NotifyUtils.removeNotify();
        OtaAgentPolicy.checkVersion().enqueue(new ICheckVersionCallback() {
            @Override
            public void onCheckSuccess(List<VersionInfo> list) {
                SPFTool.putBoolean(SP_IS_LOCAL_UPDATE, false);
                if (iCheckVersionCallback != null) {
                    iCheckVersionCallback.onCheckSuccess(list);
                }
                if (null == policyManager) {
                    Trace.d(TAG, "onCheckSuccess() policy  manager is invalid");
                    try {
                        policyManager = OtaAgentPolicy.getPolicy(OtaAgentPolicy.getOtaEntityController().getMainEntity().getProductInfo().productId);
                    } catch (FotaException e) {
                        e.printStackTrace();
                        Trace.e(TAG, "onCheckSuccess() Exception: ", e);
                    }
                }
                if (isAutoCheck) {
                    //客户端触发
                    if (policyManager.isDownloadForce()) {
                        boolean canDownload = !policyManager.isRequestWifi() || NetUtils.NETWORK_WIFI.equals(NetUtils.getNetworkState(App.sCx));
                        //如果当前设备的网络为wifi，或者策略为任意网络都能下载
                        if (canDownload) {
                            Trace.d(TAG, "onReceiverNewVersion() is Download Force and not request wifi");
                            OtaService.startService(OtaService.ACTION_DOWNLOAD_TASK, TRIGGER.DOWNLOAD.DOWNLOAD_AUTO.name());
                        }
                        //强制下载但是 WiFi 策略不满足时也不提示
                        Trace.d(TAG, "Download force condition not satisfied");
                        return;
                    }
                    startService(ACTION_DOWNLOAD_TASK, TRIGGER.DOWNLOAD.DOWNLOAD_AUTO.name());
                }
            }

            @Override
            public void onCheckFail(int i) {
                if (iCheckVersionCallback != null) {
                    iCheckVersionCallback.onCheckFail(i);
                }
            }
        });
    }


    private void downloadTask(Intent intent) {
        //设置下载Trigger
        final String trigger = intent.getStringExtra(EXTRA_PARAM1);
        //判定触发下载的方式是否界面点击下载
        uiTrigger = TRIGGER.DOWNLOAD.DOWNLOAD_UI.name().equals(trigger);
        //判断触发下载的方式是否自动下载
        autoTrigger = TRIGGER.DOWNLOAD.DOWNLOAD_AUTO.name().equals(trigger);
        if (autoTrigger) {
            //自动下载的话，自动下载次数 +1
            ((App) App.sCx).getDB().increaseDownloadTime();
        }
        NotifyUtils.removeNotify();
        OtaAgentPolicy.download()
                .enqueue(new IDownSimpleListener() {
                    @Override
                    public void on_start() {
                        Trace.d(TAG, "on_start ");
                        if (null != iDownListener) {
                            iDownListener.onStart();
                        }
                    }

                    @Override
                    public void onDownloadProgress(String s, long l, long l1, int i) {
                        Trace.d(TAG, "onDownloadProgress: " + i);
                        RecordData.downloadProgress = i;
                        if (null != iDownListener) {
                            iDownListener.onDownloadProgress(i);
                        }
                        if (ActivityCollector.isShowing()) {
                            NotifyUtils.removeNotify();
                        }
                        if (uiTrigger && !ActivityCollector.isShowing()) {
                            NotifyUtils.notifyDownloading(i);
                        }
                    }

                    /**
                     * 下载完成回调
                     * @param successProductIds 下载成功的项目ID
                     * @param failedProductIds  下载失败的项目ID，其中int值为错误码
                     */
                    @Override
                    public void onFinished(List<String> successProductIds, Map<String, Integer> failedProductIds) {
                        if (ActivityCollector.isShowing()) {
                            NotifyUtils.removeNotify();
                        }
                        if (failedProductIds == null || failedProductIds.size() == 0) {
                            RecordData.downloadProgress = 100;
                            if (null != iDownListener) {
                                iDownListener.onSuccess();
                            }
                            //重置下载次数
                            Dispatcher.getDispatcher().enqueue(new NamedRunnable("download time reset") {
                                @Override
                                protected void execute() {
                                    ((App) App.sCx).getDB().resetDownloadTime();
                                }
                            });
                            if (null == policyManager) {
                                Trace.d(TAG, "onFinished() policy  manager is invalid");
                                try {
                                    policyManager = OtaAgentPolicy.getPolicy(OtaAgentPolicy.getOtaEntityController().getMainEntity().getProductInfo().productId);
                                } catch (FotaException e) {
                                    e.printStackTrace();
                                    Trace.e(TAG, "onFinished() Exception: ", e);
                                }
                            }
                            //由后台触发的强制下载
                            if (autoTrigger) {
                                if (policyManager.isForceInstall() || SPFTool.getBoolean(Constant.SP_OTA_SILENT_UPDATE, false)) {
                                    Trace.d(TAG, "download finish ,will install force");
                                    NotifyUtils.notifyDownloadFinish(true);
                                    //在显示时间过后，执行安装操作
                                    Dispatcher.getDispatcher().enqueue(new NamedRunnable("WILL INSTALL TASK") {
                                        @Override
                                        protected void execute() {
                                            SystemClock.sleep(NotifyUtils.FORCE_INSTALL_SHOW_TIME * 1000);
                                            startService(ACTION_INSTALL_TASK, TRIGGER.UPGRADE.UPGRADE_FORCE.name());
                                        }
                                    });
                                } else {
                                    Trace.d(TAG, "download finish, isn't foce install");
                                    NotifyUtils.notifyDownloadFinish(false);
                                }
                            } else if (TRIGGER.DOWNLOAD.DOWNLOAD_UI.name().equals(trigger)) {
                                if (!ActivityCollector.isShowing()) {
                                    NotifyUtils.notifyDownloadFinish(false);
                                }
                            }
                        } else {
                            RecordData.downloadProgress = 1;
                            if (null != iDownListener) {
                                int errorCode = 0;
                                for (Integer code : failedProductIds.values()) {
                                    errorCode = code;
                                }
                                iDownListener.onFailed(errorCode);
                            }
                            //界面点击触发下载失败，APP 未处于前台显示的话，则通知栏提示
                            if (uiTrigger && !ActivityCollector.isShowing()) {
                                NotifyUtils.notifyDownloadFailed();
                            }
                        }
                    }

                    @Override
                    public void onCancel() {
                        if (null != iDownListener) {
                            iDownListener.onCancel();
                        }
                    }
                });
    }

    private void installTask(Intent intent) {
        // 设置Trigger
        String trigger = intent.getStringExtra(EXTRA_PARAM1);
        //判定是否界面点击触发升级
        uiTrigger = TRIGGER.UPGRADE.UPGRADE_UI.name().equals(trigger);
        //判断是否强制升级
        autoTrigger = TRIGGER.UPGRADE.UPGRADE_FORCE.name().equals(trigger);
        NotifyUtils.removeNotify();
        OtaAgentPolicy.update()
                .install(otaEntity.getProductInfo().productId, new InstallListener() {
                    @Override
                    public void onUpgradeProgress(int i, int i1) {
                        RecordData.upgradeProgress = i1;
                        if (null != iRebootUpgradeCallBack) {
                            iRebootUpgradeCallBack.onUpgrading(i1);
                        }
                        if (ActivityCollector.isShowing()) {
                            NotifyUtils.removeNotify();
                        }
                        if (i1 == 100) {
                            onUpgradeSuccess();
                            return;
                        }
                        //Ui 触发的升级，且 APP 不在前台显示
                        if (uiTrigger && !ActivityCollector.isShowing()) {
                            NotifyUtils.notifyUpgrading(i1);
                        }
                    }

                    @Override
                    public void onUpgradeSuccess() {
                        if (null != iRebootUpgradeCallBack) {
                            iRebootUpgradeCallBack.onSuccess();
                        }
                        if (ActivityCollector.isShowing()) {
                            NotifyUtils.removeNotify();
                        }
                        if (null == policyManager) {
                            Trace.d(TAG, "onUpgradeSuccess() policy  manager is invalid");
                            try {
                                policyManager = OtaAgentPolicy.getPolicy(OtaAgentPolicy.getOtaEntityController().getMainEntity().getProductInfo().productId);
                            } catch (FotaException e) {
                                e.printStackTrace();
                                Trace.e(TAG, "onUpgradeSuccess() Exception: ", e);
                            }
                        }
                        //强制升级且满足强制升级前置条件以及设备息屏
                        if (autoTrigger) {
                            if (policyManager.isForceInstall()) {
                                Trace.d(TAG, "Install success, will reboot ");
                                Utils.reboot();
                                return;
                            }
                            Trace.d(TAG, "Reboot condition not satisfied");
                            return;
                        }
                        //判断是否 UI 触发的升级，如果不延时 0.5 s 会出现通知内容没有更新的情况
                        if (uiTrigger && !ActivityCollector.isShowing()) {
                            new Thread() {
                                @Override
                                public void run() {
                                    try {
                                        Thread.sleep(500);
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                    NotifyUtils.notifyAbupdateSuccess();
                                    super.run();
                                }
                            }.start();
                        }
                    }

                    @Override
                    public void onUpgradeFail(int i) {
                        RecordData.upgradeProgress = 0;
                        if (null != iRebootUpgradeCallBack) {
                            iRebootUpgradeCallBack.onError(i);
                        }
                        if (ActivityCollector.isShowing()) {
                            NotifyUtils.removeNotify();
                        }
                        //界面点击触发升级失败，APP 不在前台显示的话，则通知栏提示
                        if (uiTrigger && !ActivityCollector.isShowing()) {
                            NotifyUtils.notifyAbupdateFailed();
                        }
                    }
                });
    }

    private void showNotification() {
        OtaStatus curStatus = OtaStatusMgr.getInstance().getCurStatus();
        if (curStatus == OtaStatus.DOWNLOADING) {
            if (uiTrigger && !ActivityCollector.isShowing()) {
                NotifyUtils.notifyDownloading(RecordData.downloadProgress);
            }
        } else if (curStatus == OtaStatus.UPGRADING) {
            if (uiTrigger && !ActivityCollector.isShowing()) {
                NotifyUtils.notifyUpgrading(RecordData.upgradeProgress);
            }
        }
    }


    /**
     * 强制升级Intent第二个参数为本地升级文件绝对路径
     *
     * @param intent
     */
    private void localInstallTask(Intent intent) {
        // 设置Trigger
        uiTrigger = TRIGGER.UPGRADE.UPGRADE_UI.name().equals(intent.getStringExtra(EXTRA_PARAM1));
        String localFilePath = intent.getStringExtra(EXTRA_PARAM2);
        NotifyUtils.removeNotify();
        //本地升级仅需根据是否在前台显示来判断是否需要通知栏提示即可
        OtaAgentPolicy.update()
                .installByLocal(otaEntity.getProductInfo().productId, localFilePath, new InstallListener() {
                    @Override
                    public void onUpgradeProgress(int i, int i1) {
                        RecordData.upgradeProgress = i1;
                        if (null != iRebootUpgradeCallBack) {
                            iRebootUpgradeCallBack.onUpgrading(i1);
                        }
                        if (i1 == 100) {
                            onUpgradeSuccess();
                            return;
                        }
                        if (ActivityCollector.isShowing()) {
                            NotifyUtils.removeNotify();
                        } else {
                            NotifyUtils.notifyUpgrading(i1);
                        }
                    }

                    @Override
                    public void onUpgradeSuccess() {
                        if (null != iRebootUpgradeCallBack) {
                            iRebootUpgradeCallBack.onSuccess();
                        }
                        if (ActivityCollector.isShowing()) {
                            NotifyUtils.removeNotify();
                        } else {
                            new Thread() {
                                @Override
                                public void run() {
                                    try {
                                        Thread.sleep(500);
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                    NotifyUtils.notifyAbupdateSuccess();
                                    super.run();
                                }
                            }.start();
                        }
                    }

                    @Override
                    public void onUpgradeFail(int i) {
                        RecordData.upgradeProgress = 0;
                        if (null != iRebootUpgradeCallBack) {
                            iRebootUpgradeCallBack.onError(i);
                        }
                        if (ActivityCollector.isShowing()) {
                            NotifyUtils.removeNotify();
                        } else {
                            NotifyUtils.notifyAbupdateFailed();
                        }
                    }
                });
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Trace.d(TAG, "onBind() ");
        return otaBinder;
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        if (intent != null) {
            String action = intent.getAction();
            try {
                if (null == policyManager) {
                    String productId = OtaAgentPolicy.getOtaEntityController().getMainEntity().getProductInfo().productId;
                    Log.d(TAG, "onHandleIntent: "+productId);
                    policyManager = OtaAgentPolicy.getPolicy(productId);
                }
            } catch (FotaException e) {
                e.printStackTrace();
            }
            switch (action) {
                case ACTION_CHECK_VERSION_TASK:
                    checkVersionTask(intent);
                    break;
                case ACTION_DOWNLOAD_TASK:
                    downloadTask(intent);
                    break;
                case ACTION_INSTALL_TASK:
                    installTask(intent);
                    break;
                case ACTION_LOCAL_INSTALL_TASK:
                    localInstallTask(intent);
                    break;
                case ACTION_SHOW_NOTIFICATION:
                    showNotification();
                    break;
                default:
                    break;
            }
        }
    }

    @Override
    public void onCreate() {
        Trace.d(TAG, "onCreate() ");
        super.onCreate();
        fotaInject = FotaInjector.inject(this);
    }

    @Override
    public void onDestroy() {
        Trace.d(TAG, "onDestroy() ");
        if (null != fotaInject) {
            fotaInject.unInject();
        }
        super.onDestroy();
    }

    public class OtaBinder extends Binder {

        public void checkVersion(TRIGGER.CHECK trigger, ICheckVersionCallback callback) {
            iCheckVersionCallback = callback;
            OtaService.startService(ACTION_CHECK_VERSION_TASK, trigger.name());
        }

        public void download(TRIGGER.DOWNLOAD trigger, IDownloadInter onDownListener) {
            iDownListener = onDownListener;
            OtaService.startService(ACTION_DOWNLOAD_TASK, trigger.name());
        }

        public boolean downloadCancel() {
            return OtaAgentPolicy.download().downloadCancel();
        }

        public void upgrade(TRIGGER.UPGRADE trigger, IRebootUpgradeCallBack callback) {
            iRebootUpgradeCallBack = callback;
            OtaService.startService(ACTION_INSTALL_TASK, trigger.name());
        }

        public void localUpgrade(String localFilePath, TRIGGER.UPGRADE trigger, IRebootUpgradeCallBack callback) {
            iRebootUpgradeCallBack = callback;
            Intent intent = new Intent(App.sCx, OtaService.class);
            intent.setAction(ACTION_LOCAL_INSTALL_TASK);
            intent.putExtra(EXTRA_PARAM1, trigger.name());
            intent.putExtra(EXTRA_PARAM2, localFilePath);
            App.sCx.startService(intent);
        }
    }

    public static void startService(String action, String trigger) {
        Intent intent = new Intent(App.sCx, OtaService.class);
        intent.setAction(action);
        if (!action.equals(ACTION_SHOW_NOTIFICATION)) {
            intent.putExtra(EXTRA_PARAM1, trigger);
        }
        App.sCx.startService(intent);
    }

    public static void registerDownloadListener(IDownloadInter onDownListener) {
        iDownListener = onDownListener;
    }

    public static void registerUpgradeListener(IRebootUpgradeCallBack upgradeCallBack) {
        iRebootUpgradeCallBack = upgradeCallBack;
    }

    public static void unRegisterDownloadListener() {
        iDownListener = null;
    }

    public static void unRegisterUpgradeListener() {
        iRebootUpgradeCallBack = null;
    }
}
